package com.hit.sys.core.filter.security;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.log.Log;
import com.hit.core.context.request.RequestNoContext;
import com.hit.core.exception.AuthException;
import com.hit.core.exception.enums.ServerExceptionEnum;
import com.hit.core.pojo.login.SysLoginUser;
import com.hit.core.util.ResponseUtil;
import com.hit.sys.modular.auth.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Component
public class JwtAuthenticationTokenFilter extends OncePerRequestFilter {

    private static final Log log = Log.get();

    @Autowired
    private AuthService authService;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException {
        try {
            doFilter(request, response, filterChain);
        } catch (Exception e) {
            log.error(">>> 服务器运行异常，请求号为：{}，具体信息为：{}", RequestNoContext.get(), e.getMessage());
            ResponseUtil.responseExceptionError(response, ServerExceptionEnum.SERVER_ERROR.getCode(),
                    ServerExceptionEnum.SERVER_ERROR.getMessage(), e.getStackTrace()[0].toString());
        }
    }

    private void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws IOException, ServletException {
        SysLoginUser sysLoginUser = null;
        try {
            String token = authService.getTokenFromRequest(request);
            if (StrUtil.isNotEmpty(token)) {
                sysLoginUser = authService.getLoginUserByToken(token);
            }
        } catch (AuthException exception) {
            //token过期或者token失效的情况，响应给前端
            ResponseUtil.responseExceptionError(response, exception.getCode(), exception.getErrorMessage(), exception.getStackTrace()[0].toString());
            return;
        }

        if (ObjectUtil.isNotNull(sysLoginUser)) {
            authService.setSpringSecurityContextAuthentication(sysLoginUser);
        }

        filterChain.doFilter(request, response);
    }
}
